package start.spring.basic.demo.service.demo.impl;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;

import lombok.extern.slf4j.Slf4j;
import start.spring.basic.demo.common.DemoConstant;
import start.spring.basic.demo.dao.GgPzSysMapper;
import start.spring.basic.demo.dao.TestMapper;
import start.spring.basic.demo.entity.GgPzSys;
import start.spring.basic.demo.entity.Test;
import start.spring.basic.demo.service.BaseServiceImpl;
import start.spring.basic.demo.service.demo.IDemoService;
import start.spring.basic.demo.service.singletable.TestService;
import start.spring.basic.dynamic.DsConstant;
import start.spring.basic.exception.common.DbException;
import start.spring.basic.log.ServiceDetails;
import start.spring.basic.page.PageQuery;
import start.spring.basic.page.PageResult;
import start.spring.basic.redis.RedisKey;
import start.spring.basic.response.ResponseData;
import start.spring.basic.util.PageUtil;
import start.spring.basic.util.common.DBUtil;
import start.spring.basic.util.common.StringUtil;

/**
 * 
 * ****************************************************************************
 * 开发样例业务逻辑实现
 *
 * @author(作者)：xuyongyun	
 * @date(创建日期)：2021年4月8日
 ******************************************************************************
 */
@Slf4j
@Service
public class DemoServiceImpl extends BaseServiceImpl implements IDemoService {
	
	@Autowired
	GgPzSysMapper ggPzSysMapper;
	
	@Autowired
	TestMapper testMapper;
	
	@Autowired
	TestService testService;
	
	@Autowired
	ServiceDetails serviceDetails;

	@Override
	public ResponseData<JSONObject> operateRedis() {
		super.redis.set(RedisKey.REDIS_DEFAULT, "a", String.valueOf(System.currentTimeMillis()));
		super.redis.set(RedisKey.REDIS_01, "b", "btest");
		
		JSONObject result = new JSONObject();
		result.put(RedisKey.REDIS_DEFAULT, super.redis.get(RedisKey.REDIS_DEFAULT, "a"));
		result.put(RedisKey.REDIS_01, super.redis.get(RedisKey.REDIS_01, "b"));
		return ResponseData.success("操作redis成功",result);
	}

	@Override
	public ResponseData<List<GgPzSys>> MpQertyAll() {
		return ResponseData.successData(this.ggPzSysMapper.selectList(null));
	}

	@Override
	public PageResult<GgPzSys> mpQueryPage(PageQuery pageQuery) {
		IPage<GgPzSys> page = super.getPage(pageQuery);
		QueryWrapper<GgPzSys> queryWrapper = new QueryWrapper<>();
		page = this.ggPzSysMapper.selectPage(page, queryWrapper);
		return super.getPageResult(page);
	}

	@Override
	@DS(DsConstant.XTGL)
	public PageResult<Test> mpMultiDbQueryPage(PageQuery pageQuery, String a) {
		IPage<Test> page = super.getPage(pageQuery);
		QueryWrapper<Test> queryWrapper = new QueryWrapper<>();
		if(!StringUtil.isEmpty(a)) {
			queryWrapper.eq("a", a);
		}
		page = this.testMapper.selectPage(page, queryWrapper);
		serviceDetails.saveDetails(DemoConstant.SYSTEM_TYPE, "测试service记录日志", null, null, page);
		return super.getPageResult(page);
	}

	@Override
	@DS(DsConstant.XTGL)
	public PageResult<Test> mbMultiDbQueryPage(PageQuery pageQuery, String a) {
		IPage<Test> page = super.getPage(pageQuery);
		page = this.testMapper.queryPramsList(page, a);
		return super.getPageResult(page);
	}

	@Override
	public PageResult<GgPzSys> jtQueryPage(PageQuery pageQuery) {
		
		PageUtil<GgPzSys> page = super.getPageUtil(pageQuery);
		String sql = "select * from gg_pz_sys t";
		page = super.dao.queryByPageMysql(sql, null, page, null, GgPzSys.class);
		return super.getPageResult(page);
	}

	@DS(DsConstant.XTGL)
	@Override
	public PageResult<Test> jtMultiDbQueryPage(PageQuery pageQuery, String a) {
		PageUtil<Test> page = super.getPageUtil(pageQuery);
		String sql = "select * from test ";
		String[] prams = null;
		if(!StringUtil.isEmpty(a)) {
			sql += "where a = ?";
			prams = new String[] {a};
		}
		page = super.dao.queryByPageMysql(sql, prams, page, null, Test.class);
		return super.getPageResult(page);
	}
	
	@Override
	public ResponseData<String> jdbcOperate() {
		Connection connDefault = null;
		PreparedStatement psDefault = null;
		
		Connection connXtgl = null;
		PreparedStatement psXtgl = null;
		try {
			
			//基于jdbc的查询
			String sqlQuery = "select * from test where a = ?";
			String[] prams = {"a1"};
			PageUtil<Test> page = super.getPageUtil(null);
			page = super.dynamicJdbc.queryByPageMysql(DsConstant.XTGL, sqlQuery, prams, page, null, Test.class);
			log.info("总记录数：" + page.totalRecords);
			
			//基于jdbc的事务操作
			connDefault = DBUtil.getConnection(super.getDs(DsConstant.DEFAULT));
			connXtgl = DBUtil.getConnection(super.getDs(DsConstant.XTGL));
			
			DBUtil.setAutoCommit(connDefault, false);
			DBUtil.setAutoCommit(connXtgl, false);
			
			String sqlTest = "update test t set t.b = ? where t.a = 'a1' ";
			psXtgl = connXtgl.prepareStatement(sqlTest);
			psXtgl.setString(1, "234");
			psXtgl.executeUpdate();
			
			String sqlDefault = "INSERT INTO gg_pz_sys (PZDM, PZZ, XTDM, XGBZ, BZ) VALUES (?, ?, ?, 'N', ?)";
			psDefault = connDefault.prepareStatement(sqlDefault);
			psDefault.setString(1, "testa");
			psDefault.setString(2, "a");
			psDefault.setString(3, "11");
			psDefault.setString(4, "测试a");
			psDefault.executeUpdate();
			
			connXtgl.commit();
			connDefault.commit();
		}catch(Exception e) {
			DBUtil.rollBack(connDefault);
			DBUtil.rollBack(connXtgl);
			throw new DbException(e.getMessage(),e.getCause());
		}finally {
			
			DBUtil.setAutoCommit(connDefault, true);
			DBUtil.setAutoCommit(connXtgl, true);
			
			DBUtil.closePreparedStatement(psXtgl);
			DBUtil.closePreparedStatement(psDefault);
			
			DBUtil.closeConnection(connXtgl);
			DBUtil.closeConnection(connDefault);
		}
		return ResponseData.success();
	}
	
	@Transactional
	@Override
	@DS(DsConstant.XTGL)
	public ResponseData<String> mpUidGenerator() {
		
		Test test1 = new Test();
		test1.setA("a1");
		test1.setB("b1");
		
		this.testService.save(test1);
		
		List<Test> testList = new ArrayList<>();
		Test test2 = new Test();
		test2.setA("a2");
		test2.setB("b2");
		testList.add(test2);
		
		Test test3 = new Test();
		test3.setA("a3");
		test3.setB("b3");
		testList.add(test3);
		
		this.testService.saveBatch(testList);
		
		return ResponseData.success();
	}
	
	@Transactional
	@DS(DsConstant.XTGL)
	@Override
	public ResponseData<String> jtUidGenerator() {
		
		String sql = "INSERT INTO test(id, a, b)VALUES (?, ?, ?)";
		
		Object[] prams = {super.idGenerator.nextNumberId(),"a1","b1"};
		super.dao.excute(sql, prams);
		
		List<Object[]> paramsList = new ArrayList<>();
		Object[] prams2 = {super.idGenerator.nextNumberId(),"a2","b2"};
		Object[] prams3 = {super.idGenerator.nextNumberId(),"a3","b3"};
		paramsList.add(prams2);
		paramsList.add(prams3);
		super.dao.batchExcute(sql, paramsList);
		
		return ResponseData.success();
	}
}
